package org.aceor.funny.common.http.retrofit;

import org.aceor.funny.common.http.retrofit.serializer.Serializer;
import org.aceor.funny.common.http.utils.TypeUtils;
import org.aceor.funny.common.http.executor.HttpRequestHandler;
import org.aceor.funny.common.http.retrofit.parser.HttpRequest;
import org.aceor.funny.common.http.retrofit.parser.HttpRequestFactory;
import org.aceor.funny.common.http.retrofit.serializer.DefaultSerializer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by lxue on 15/11/20.
 */
public class SimpleRetrofit implements InvocationHandler{

    private static final Logger log = LoggerFactory.getLogger(SimpleRetrofit.class);
    private final String baseUrl;
    private final Serializer serializer;
    private final HttpRequestHandler handler;
    private SimpleRetrofit(String baseUrl, Serializer serializer, HttpRequestHandler handler) {
        this.baseUrl = baseUrl;
        this.serializer = serializer;
        this.handler = handler;
    }

    public <T> T create(final Class<T> serviceClass){

        TypeUtils.singleInterfaceCheck(serviceClass);

        return (T)Proxy.newProxyInstance(serviceClass.getClassLoader(),new Class[]{serviceClass},this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //解析并构造HttpRequest请求对象
        HttpRequest request = HttpRequestFactory.createRequest(method, args, this);
        log.info("SimpleRetrofit HttpRequest Create--{}",request);
        if(request.isAsync()){
            //采用异步
            handler.handleAsync(request);
            return null;
        }else{
            //采用同步
            return handler.handle(request, request.getReturnClazz());
        }
    }


    public static final class Builder{
        Serializer serializer;
        String baseUrl;
        HttpRequestHandler handler;

        public Builder baseUrl(String url){
            if(!StringUtils.isNoneEmpty(url)){
                throw new NullPointerException("base url cannot be null or empty");
            }
            this.baseUrl = url;
            return this;
        }

        public <T> Builder setSerializer(Serializer serializer){
            if(serializer == null){
                this.serializer = new DefaultSerializer();
            }else {
                this.serializer = serializer;
            }
            return this;
        }

        public Builder setHttpRequestHandler(HttpRequestHandler handler){
            this.handler = handler;
            return this;
        }

        public SimpleRetrofit build(){
            if(!StringUtils.isNoneEmpty(baseUrl)){
                throw new NullPointerException("base url cannot be null or empty.");
            }
            if(handler == null){
                throw new NullPointerException("HttpRequestHandler cannot be null.");
            }
            if(serializer == null){
                this.serializer = new DefaultSerializer();
            }
            return new SimpleRetrofit(baseUrl, serializer, handler);
        }

    }

    public String getBaseUrl() {
        return baseUrl;
    }

    public Serializer getSerializer() {
        return serializer;
    }
}
